Skip to content

Conversation

BennoLossin
Copy link
Contributor

I implemented the core of rust-lang/rfcs#3318 for personal experimentation and found out that you can get experimental features merged easier than a whole RFC. I do not know the correct process to do this, but I thought a PR would be the way to go.

This PR introduces field info types. These types are generated for every field of every struct. They can be named by using the core::mem::field_of!() macro also introduced by this PR.

I have not had any experience modifying the Rust compiler, so there will be mistakes. I could definitely use some help refining this, so any comments are welcomed. The way I implemented was by first looking at offset_of! then realizing I want something that resolves to a type and not an expression, I then went and took a look at how impl Trait types are implemented and copied a lot from that. At some point I also realized that type equality and trait resolution were incorrect, so I went digging and I think I fixed it.

Here a list of things to complete before even thinking about merging:

  • create an issue to use for the unstability attribute on field_of!
  • handle TODOs in the code
  • bikeshed the name FieldInfo: should the hir version be named FieldOf?
  • how to handle enums/unions?
  • can this also handle slices/arrays?
  • fix type inference, i.e. allow field_of!(_, foo)
  • remove some debugging stuff
  • solve ICEs when using cargo instead of rustc
Example Code
#![feature(field_project, offset_of)]
use std::mem::{field_of, offset_of, MaybeUninit};

unsafe trait Field {
    type Base;
    type Type;
    const OFFSET: usize;
}

trait Project<F: Field> {
    type Output;
    fn project(self) -> Self::Output;
}

impl<'a, F: Field> Project<F> for &'a mut MaybeUninit<F::Base>
where
    F::Type: 'a,
{
    type Output = &'a mut MaybeUninit<F::Type>;
    fn project(self) -> Self::Output {
        let ptr = self.as_mut_ptr().cast::<u8>().wrapping_add(F::OFFSET);
        unsafe { &mut *ptr.cast() }
    }
}

#[derive(Debug)]
struct Foo {
    value: usize,
    next: Option<Box<Foo>>,
}

unsafe impl Field for field_of!(Foo, value) {
    type Base = Foo;
    type Type = usize;
    const OFFSET: usize = offset_of!(Foo, value);
}

unsafe impl Field for field_of!(Foo, next) {
    type Base = Foo;
    type Type = Option<Box<Foo>>;
    const OFFSET: usize = offset_of!(Foo, next);
}

fn main() {
    let mut foo = MaybeUninit::uninit();
    Project::<field_of!(Foo, value)>::project(&mut foo).write(42);
    Project::<field_of!(Foo, next)>::project(&mut foo).write(Some(Box::new(Foo {
        value: 84,
        next: None,
    })));
    println!("{:?}", unsafe { foo.assume_init_ref() });
}

Output: Foo { value: 42, next: Some(Foo { value: 84, next: None }) }

@rustbot
Copy link
Collaborator

rustbot commented Dec 5, 2023

r? @b-naber

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Dec 5, 2023
@rustbot
Copy link
Collaborator

rustbot commented Dec 5, 2023

Some changes occurred to the CTFE / Miri engine

cc @rust-lang/miri

This PR changes Stable MIR

cc @oli-obk, @celinval, @spastorino, @ouz-a

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred to the core trait solver

cc @rust-lang/initiative-trait-system-refactor

@rust-log-analyzer
Copy link
Collaborator

The job mingw-check-tidy failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
Prepare all required actions
Getting action download info
Download action repository 'actions/checkout@v4' (SHA:b4ffde65f46336ab88eb53be808477a3936bae11)
Download action repository 'actions/upload-artifact@v3' (SHA:a8a3f3ad30e3422c9c7b888a15615d19a852ae32)
Complete job name: PR - mingw-check-tidy
git config --global core.autocrlf false
shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
---
GITHUB_ACTION=__run_7
GITHUB_ACTIONS=true
GITHUB_ACTION_REF=
GITHUB_ACTION_REPOSITORY=
GITHUB_ACTOR=y86-dev
GITHUB_API_URL=https://api.github.com
GITHUB_BASE_REF=master
GITHUB_ENV=/home/runner/work/_temp/_runner_file_commands/set_env_6ada0e6d-a063-4ff0-b924-9aa806e7afd6
GITHUB_EVENT_NAME=pull_request
---
GITHUB_SERVER_URL=https://github.com
GITHUB_SHA=1191f6ebd903863da1bb54607b8891698bea7837
GITHUB_STATE=/home/runner/work/_temp/_runner_file_commands/save_state_6ada0e6d-a063-4ff0-b924-9aa806e7afd6
GITHUB_STEP_SUMMARY=/home/runner/work/_temp/_runner_file_commands/step_summary_6ada0e6d-a063-4ff0-b924-9aa806e7afd6
GITHUB_TRIGGERING_ACTOR=y86-dev
GITHUB_WORKFLOW_REF=rust-lang/rust/.github/workflows/ci.yml@refs/pull/118658/merge
GITHUB_WORKFLOW_SHA=1191f6ebd903863da1bb54607b8891698bea7837
GITHUB_WORKSPACE=/home/runner/work/rust/rust
GOROOT_1_19_X64=/opt/hostedtoolcache/go/1.19.13/x64
---
Removing intermediate container 75fd1c05e799
 ---> e116903969ac
Step 6/10 : COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
 ---> 14e1bcc900d0
Step 7/10 : RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt     && pip3 install virtualenv
Collecting binaryornot==0.4.4
  Downloading binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB)
Collecting boolean-py==4.0
  Downloading boolean.py-4.0-py3-none-any.whl (25 kB)
---
Building wheels for collected packages: reuse
  Building wheel for reuse (pyproject.toml): started
  Building wheel for reuse (pyproject.toml): finished with status 'done'
  Created wheel for reuse: filename=reuse-1.1.0-cp310-cp310-manylinux_2_35_x86_64.whl size=180123 sha256=f323ccf11d14c5b11f6d5e70edb46e391f4b49a5df5c7d922224477ad8ee15c5
  Stored in directory: /tmp/pip-ephem-wheel-cache-rc4op7w1/wheels/c2/3c/b9/1120c2ab4bd82694f7e6f0537dc5b9a085c13e2c69a8d0c76d
Installing collected packages: boolean-py, binaryornot, setuptools, reuse, python-debian, markupsafe, license-expression, jinja2, chardet
  Attempting uninstall: setuptools
    Found existing installation: setuptools 59.6.0
    Not uninstalling setuptools at /usr/lib/python3/dist-packages, outside environment /usr
---
  Downloading virtualenv-20.25.0-py3-none-any.whl (3.8 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.8/3.8 MB 61.6 MB/s eta 0:00:00
Collecting filelock<4,>=3.12.2
  Downloading filelock-3.13.1-py3-none-any.whl (11 kB)
Collecting distlib<1,>=0.3.7
  Downloading distlib-0.3.7-py2.py3-none-any.whl (468 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 468.9/468.9 KB 134.5 MB/s eta 0:00:00
Collecting platformdirs<5,>=3.9.1
  Downloading platformdirs-4.1.0-py3-none-any.whl (17 kB)
Installing collected packages: distlib, platformdirs, filelock, virtualenv
Successfully installed distlib-0.3.7 filelock-3.13.1 platformdirs-4.1.0 virtualenv-20.25.0
Removing intermediate container 298f44070fe9
 ---> acbdfd07fece
Step 8/10 : COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
 ---> 44e51c3b5cbc
 ---> 44e51c3b5cbc
Step 9/10 : COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 ---> 12f3768d27b1
Step 10/10 : ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test            --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint
Removing intermediate container 03ba07411967
 ---> 790a811bc59b
Successfully built 790a811bc59b
Successfully tagged rust-ci:latest
Successfully tagged rust-ci:latest
##[endgroup]
Built container sha256:790a811bc59b4b960528a27b8806a5496b056fc52a1048d6228e8a719bbecee5
Uploading finished image sha256:790a811bc59b4b960528a27b8806a5496b056fc52a1048d6228e8a719bbecee5 to https://ci-caches.rust-lang.org/docker/139141a603ff222e98d20ef66f0e4eaedfc4b373e41d302ecff577f90ee0c6cf0cab092d18a8f6a073c88b362b9a680d3b2b6e5c828faaf25d1b853eabb78b1a
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
790a811bc59b   1 second ago     /bin/sh -c #(nop)  ENV SCRIPT=TIDY_PRINT_DIF…   0B        
44e51c3b5cbc   2 seconds ago    /bin/sh -c #(nop) COPY file:078ea1d11e7b7cda…   367B      
acbdfd07fece   4 seconds ago    |1 DEBIAN_FRONTEND=noninteractive /bin/sh -c…   23.9MB    
14e1bcc900d0   10 seconds ago   /bin/sh -c #(nop) COPY file:ac591dd6bc5afa66…   5.33kB    
e116903969ac   11 seconds ago   |1 DEBIAN_FRONTEND=noninteractive /bin/sh -c…   23.1MB    
---
<missing>      4 days ago       /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B        
<missing>      4 days ago       /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH     0B        
<missing>      4 days ago       /bin/sh -c #(nop)  ARG RELEASE                  0B        

<botocore.awsrequest.AWSRequest object at 0x7fb6eb6c2d50>
gzip: stdout: Broken pipe
xargs: docker: terminated by signal 13
https://ci-caches.rust-lang.org/docker/139141a603ff222e98d20ef66f0e4eaedfc4b373e41d302ecff577f90ee0c6cf0cab092d18a8f6a073c88b362b9a680d3b2b6e5c828faaf25d1b853eabb78b1a
sha256:790a811bc59b4b960528a27b8806a5496b056fc52a1048d6228e8a719bbecee5
---
DirectMap4k:      182208 kB
DirectMap2M:     7157760 kB
DirectMap1G:    11534336 kB
##[endgroup]
Executing TIDY_PRINT_DIFF=1 python2.7 ../x.py test            --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint
+ TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint
    Finished dev [unoptimized] target(s) in 0.03s
##[endgroup]
downloading https://ci-artifacts.rust-lang.org/rustc-builds-alt/e9013ac0e402ef449c5d00251d687289599137df/rust-dev-nightly-x86_64-unknown-linux-gnu.tar.xz
extracting /checkout/obj/build/cache/llvm-e9013ac0e402ef449c5d00251d687289599137df-true/rust-dev-nightly-x86_64-unknown-linux-gnu.tar.xz to /checkout/obj/build/x86_64-unknown-linux-gnu/ci-llvm
---
##[endgroup]
fmt check
tidy check
tidy: Skipping binary file check, read-only filesystem
##[error]tidy error: /checkout/compiler/rustc_ty_utils/src/sig_types.rs:98: TODO is used for tasks that should be done before merging a PR; If you want to leave a message in the codebase use FIXME
removing old virtual environment
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10'
Requirement already satisfied: pip in ./build/venv/lib/python3.10/site-packages (23.3.1)
Collecting black==23.3.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 7))
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.7/1.7 MB 18.0 MB/s eta 0:00:00
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.7/1.7 MB 18.0 MB/s eta 0:00:00
Collecting click==8.1.3 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 34))
  Downloading click-8.1.3-py3-none-any.whl (96 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 703.6 kB/s eta 0:00:00
Collecting importlib-metadata==6.7.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 38))
  Downloading importlib_metadata-6.7.0-py3-none-any.whl (22 kB)
Collecting mypy-extensions==1.0.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 42))
  Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB)
Collecting packaging==23.1 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 46))
  Downloading packaging-23.1-py3-none-any.whl (48 kB)
Collecting pathspec==0.11.1 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 50))
  Downloading pathspec-0.11.1-py3-none-any.whl (29 kB)
  Downloading pathspec-0.11.1-py3-none-any.whl (29 kB)
Collecting platformdirs==3.6.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 54))
  Downloading platformdirs-3.6.0-py3-none-any.whl (16 kB)
Collecting ruff==0.0.272 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 58))
  Downloading ruff-0.0.272-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.9 MB)
Collecting tomli==2.0.1 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 77))
  Downloading tomli-2.0.1-py3-none-any.whl (12 kB)
Collecting typed-ast==1.5.4 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 81))
  Downloading typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (877 kB)
  Downloading typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (877 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 877.7/877.7 kB 118.4 MB/s eta 0:00:00
Collecting typing-extensions==4.6.3 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 107))
  Downloading typing_extensions-4.6.3-py3-none-any.whl (31 kB)
Collecting zipp==3.15.0 (from -r /checkout/src/tools/tidy/config/requirements.txt (line 114))
  Downloading zipp-3.15.0-py3-none-any.whl (6.8 kB)
Installing collected packages: zipp, typing-extensions, typed-ast, tomli, ruff, platformdirs, pathspec, packaging, mypy-extensions, click, importlib-metadata, black
Successfully installed black-23.3.0 click-8.1.3 importlib-metadata-6.7.0 mypy-extensions-1.0.0 packaging-23.1 pathspec-0.11.1 platformdirs-3.6.0 ruff-0.0.272 tomli-2.0.1 typed-ast-1.5.4 typing-extensions-4.6.3 zipp-3.15.0
some tidy checks failed
Build completed unsuccessfully in 0:00:59
  local time: Tue Dec  5 23:47:55 UTC 2023
  network time: Tue, 05 Dec 2023 23:47:55 GMT

@bors
Copy link
Collaborator

bors commented Dec 6, 2023

☔ The latest upstream changes (presumably #118679) made this pull request unmergeable. Please resolve the merge conflicts.

@b-naber
Copy link
Contributor

b-naber commented Dec 16, 2023

Can you convert this to a draft PR?

Unfortunately I currently don't have enough time to help you with any of the outstanding implementation problems. Have you tried asking for help on zulip?

@BennoLossin BennoLossin marked this pull request as draft December 16, 2023 18:57
@BennoLossin
Copy link
Contributor Author

Thanks for the info, I will go ask there.

@Dylan-DPC
Copy link
Member

@y86-dev any updates on this pr?

@BennoLossin
Copy link
Contributor Author

currently I am very busy. @nbdd0121 created an improved version some time ago: https://github.com/nbdd0121/rust/tree/field-projection

@Dylan-DPC
Copy link
Member

Closing this in favour of the improved version

@nbdd0121 can you submit a draft pr here with those changes (even if wip) and mention this pr in the description, makes it easier for future tracking.

@Dylan-DPC Dylan-DPC closed this Feb 22, 2024
@Dylan-DPC Dylan-DPC removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 22, 2024
@nyabinary
Copy link

bump @nbdd0121

@BennoLossin BennoLossin deleted the field-projection branch August 15, 2025 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants